/**
 * @author		Sergey Suzdalskiy
 * @e-mail:		sergey.suzdalskiy@gmail.com
 */
package ua.kiev.gcore.render
{
import flash.display.BitmapData;
import flash.display.ShaderJob;
import flash.display.Sprite;
import flash.events.EventDispatcher;

public class BaseRenderObject extends EventDispatcher
	{		
		public var uid:String;
		
		
		public var src:Sprite;		
		public var animationSprite:Sprite;		
		
		public var alpha:Number;
		
		public var layerSRC:Array;
		public var layerMask:Array;
		public var layerColor:Array;
		
		public var freamCount:int;
		
		public var offX:Object;
		public var offY:Object;		
		
		private var combineBitmapResult:BitmapData;
		private var shaderjob:ShaderJob;
		
		private var color:uint;
		private var action:String = '';
		private var animationFream:int = 0;
		public var isAnimated:Boolean = false;
		public var isAllDataLoaded:Boolean = false;
		public var loops:int = -1;		
		public var drawDict:Object = new Object();
		
		public function BaseRenderObject()
		{			
			src = new Sprite();
			animationSprite = new Sprite();
			src.addChild(animationSprite);
			layerSRC = new Array();
			layerMask = new Array();
			layerColor = new Array();
			offX = {"a45":"0","a135":"0","a225":"0","a315":"0"};
			offY = {"a45":"-70","a135":"-70","a225":"-70","a315":"-70"};
			
			alpha = 1;
		}
/*		
		public function setLayers(src:Array, mask:Array, color:Array):void{
			layerSRC = src || new Array();
			layerMask = mask || new Array();
			layerColor = color || new Array();
			
			var assets:Object;
			var loaderUID:String = '';
			
			if(layerSRC.length){
				for each(var srcId:String in layerSRC){					
					if(AssetsStorage.check(srcId) == 1){
						if(!assets){
							assets = new Object();
						}
						loaderUID += srcId;
						assets[srcId] = AssetsStorage.assetsURL[srcId];
					}					
				}
			}
			
			if(layerMask.length){
				for each(var maskId:String in layerMask){
					if(AssetsStorage.check(maskId) == 1){
						if(!assets){
							assets = new Object();
						}
						loaderUID += maskId;
						assets[maskId] = AssetsStorage.assetsURL[maskId];
					}
				}
			}
			
			if(layerColor.length){
				for each(var maskColorId:String in layerColor){	
					if(AssetsStorage.check(maskColorId) == 1){
						if(!assets){
							assets = new Object();
						}
						loaderUID += maskColorId;
						assets[maskColorId] = AssetsStorage.assetsURL[maskColorId];
					}
				}
			}			
			if(assets){
				AssetsStorage.loadAsset(loaderUID, assets, loadComplete);
			}else{
				isAllDataLoaded = true;
			}
			drawDict = new Object();
		}								 
		
		public function loadComplete():void{			
			drawDict = new Object();
			draw();
			isAllDataLoaded = true;
		}
		
		
		public function startAnimation(loopsCount:int = -1):void{
			loops = loopsCount;
			isAnimated = true;
		}
		public function stopAnimation():void{
			animationFream = 0;	
			action = '';
			isAnimated = false;
			draw();
		}
	
		private function setCurrentFream(layers:Array, label:String):void{
			if(isAnimated){
				var isEndFreame:Boolean = false;
				for each( var mc:MovieClip in layers){
					mc.gotoAndStop(animationFream);
					if((mc.currentLabel != label)||(animationFream > mc.totalFrames)){
						mc.gotoAndStop(label);
						animationFream = mc.currentFrame;
						isEndFreame = true;
						
					}
				}
				if((isEndFreame)&&(loops != -1)){					
					if(--loops < 0){
						loops = -1;
						stopAnimation();
					}					
				}
				animationFream++;
			}else{
				for each( var mc1:MovieClip in layers){
					mc1.gotoAndStop(label);
					animationFream = mc1.currentFrame;
				}
			}			
		}
		
		public function draw(bmp:Bitmap = null, key:String = ""):void{			
			var result:Bitmap = bmp;
			
			if((!isAnimated)&&(drawDict[action+key])){
				result = drawDict[action+key];
			}
				
			if(!result){				
				result = new Bitmap(combine(ShaderStorage.getItem(ShaderStorage.COMBINE).shaderData, layerSRC, 4, action), "auto", true);
				if((color)&&(layerColor.length)){
					var colorMask:Bitmap = new Bitmap(combine(ShaderStorage.getItem(ShaderStorage.COMBINEMASKS).shaderData, layerColor, 2, direction+action));
					result = new Bitmap(colorize(ShaderStorage.getItem(ShaderStorage.COLORIZE).shaderData, color, result, colorMask), "auto", true);
				}				
				result.x = offX[direction];
				result.y = offY[direction];
				result.alpha = alpha;
			}
			
			if((!isAnimated)&&(!drawDict[direction+action+key])){
				drawDict[direction+action+key] = result;
			}
			
			while(animationSprite.numChildren){
				animationSprite.removeChildAt(0);
			}			
			animationSprite.addChild(result);			
		}
		
		public function setAlpha(a:Number):void{
			if(alpha != a){
				alpha = a;
				for each( var bmp:Bitmap in drawDict){
					bmp.alpha = alpha; 
				}
			}
		}
		
		public function drawOcclusion(item:Item, status:String, threshold1:Number, threshold2:Number):void{
			var result:Bitmap;
			var resultBD:BitmapData;
			var img1:Bitmap;
			var mask1:Bitmap;			
			var img2:Bitmap;
			var mask2:Bitmap;			
			
			if(isAllDataLoaded){
				isAnimated = false;
				
				img1 = new Bitmap(combine(ShaderStorage.shaderCombine, item.layerSRC, 4, item.direction + item.action));
				if((item.color)&&(item.layerColor.length)){
					var colorMask:Bitmap = new Bitmap(combine(ShaderStorage.shaderCombineMasks, item.layerColor, 2, item.direction+item.action));
					img1 = new Bitmap(colorize(ShaderStorage.shaderColorize, item.color, img1, colorMask));
				}			
				mask1 = new Bitmap(combine(ShaderStorage.shaderCombineMasks, item.layerMask, 2, item.direction+item.action));
				
				img2 = new Bitmap(combine(ShaderStorage.shaderCombine, layerSRC, 4, direction+action));
				mask2 = new Bitmap(combine(ShaderStorage.shaderCombineMasks, layerMask, 2, direction+action));
				
				var width:int = img1.width;
				var height:int = img1.height;
				
				resultBD = new BitmapData(width, height, true, 0x000000);	
				
				var shaderjob:ShaderJob;
				var shaderOcclusion:Shader = new Shader(ShaderStorage.shaderOcclusion);
				shaderOcclusion.data.src1.input = img1.bitmapData;
				shaderOcclusion.data.mask1.input = mask1.bitmapData;
				shaderOcclusion.data.src2.input = img2.bitmapData;
				shaderOcclusion.data.mask2.input = mask2.bitmapData;
				shaderOcclusion.data.off1.value = setOcclusionOff1(status);				
				shaderOcclusion.data.off2.value = setOcclusionOff2(status);
				
				shaderOcclusion.data.threshold.value = [threshold1];
				shaderOcclusion.data.threshold2.value = [threshold2];
				
				
				shaderjob = new ShaderJob(shaderOcclusion, resultBD, width, height);
				
				shaderjob.start(true);
				
				result = new Bitmap(resultBD,"auto",true);
				
				result.x = setOcclusionResult(status)[0];
				result.y = setOcclusionResult(status)[1];
				
				draw(result, item.uid);
			}else{
				draw();
			}
		}
	
		private function setOcclusionOff1(status:String):Array{
			return [0,0];			
		}
		
		private function setOcclusionOff2(status:String):Array{
			var result:Array = [0,0];	
			if((status == DoctorAI.WAITPATIENT)||(status == DoctorAI.WORK)){
				switch(direction){
					case "a45":												
						result = [-10,-4];								
						break;
					case "a135":				
						result = [-10,-15];
						break;
					case "a225":				
						result = [60,-17];
						break;
					case "a315":				
						result = [60,-4];
						break;
				}
			}
			return result;			
		}
		
		private function setOcclusionResult(status:String):Array{
			var result:Array = [0,0];	
			if((status == DoctorAI.WAITPATIENT)||(status == DoctorAI.WORK)){
				switch(direction){
					case "a45":	
						result = [-22, -15];														
						break;
					case "a135":
						result = [-20, 0];						
						break;
					case "a225":				
						result = [-30, 0];
						break;
					case "a315":				
						result = [-30, -15];
						break;
				}				
			}
			
			result[1] -= 70;
			
			return result
		}
		
		public function combine(shader:ByteArray, layers:Array, conut:int, label:String):BitmapData{
			var result:BitmapData;
			
			if(!layers.length){
				layers.push("empty");
				Logger.ERROR("invalid SRC array: "+layers.toString());
			}
			result = new BitmapData(60, 100, true, 0x000000);			
			if(layers.length > 1){				
				var shaderCombine:Shader = new Shader(shader);
				var texture:Array = new Array;
				for(var j:int = 0; j<conut; j++){
					if(layers[j]){
						var src:DisplayObject = AssetsStorage.getDisplayObject(layers[j]);
						if(src){
							texture.push(src['item']);
						}
					}
				}
				setCurrentFream(texture, label);
				for(var i:int = 0; i<conut; i++){																			
					var img:Bitmap = AssetsStorage.getBitmap(texture[i]) || new Bitmap(new BitmapData(1,1,true,0x000000));
					var off:Array = [img.x,img.y];
					if(shaderCombine.data['src'+String(i+1)]){
						shaderCombine.data['src'+String(i+1)].input = img.bitmapData;
					}
					if(shaderCombine.data['off'+String(i+1)]){
						shaderCombine.data['off'+String(i+1)].value = off;
					}									
				}					
				if(shaderCombine.data.threshold1){
					shaderCombine.data.threshold1.value = [0.999];
				}
				if(shaderCombine.data.threshold2){
					shaderCombine.data.threshold2.value = [0.01];
				}
				
				shaderjob = new ShaderJob(shaderCombine, result);
				shaderjob.start(true);
			}else{
				var src1:DisplayObject = AssetsStorage.getDisplayObject(layers[0], typeRender);
				if(src1){
					var mc1:MovieClip = src1['item'];
					setCurrentFream([mc1], label);					
					result = getBitmap(mc1).bitmapData;
				}else{
					result = new BitmapData(10,10,false,0xff0000);
					//Error: invalid SRC
					//Logger.ERROR("invalid SRC : "+layers[0]);
				}					  
			}
			return result;
		}
		
		private function colorize(shaer:ByteArray, color:uint, src:Bitmap, mask:Bitmap):BitmapData{
			var result:BitmapData = new BitmapData(src.width, src.height);
			var shaderColorize:Shader = new Shader(shaer);						
			var colorF:Array = [];//[color.R, color.G, color.B, 1];
			
			shaderColorize.data.src.input = src.bitmapData;
			shaderColorize.data.mask.input = mask.bitmapData;		
			shaderColorize.data.color.value = colorF;
			
			var shaderjob:ShaderJob = new ShaderJob(shaderColorize, result);
			shaderjob.start(true);
			
			return result;
		}
		*/

	}
}